package com.mrdeer.uaa.integration;

import com.alibaba.fastjson.JSON;
import com.mrdeer.uaa.api.entity.AuthPrincipal;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Map;

/**
 * 统一用户认证处理，集成了网页(简单模式、授权码模式用户登录)认证与password模式认证
 *
 * @author ：xie jianchu
 * @date ：Created in 2020/9/4 0004 17:34
 */
public class IntegrationUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    private IntegrationUserDetailsAuthenticationHandler authenticationHandler = null;

    public IntegrationUserDetailsAuthenticationProvider(IntegrationUserDetailsAuthenticationHandler authenticationHandler) {
        this.authenticationHandler = authenticationHandler;
    }

    @SuppressWarnings("deprecation")
    public IntegrationUserDetailsAuthenticationProvider(UserDetails userDetails,
                                                        UsernamePasswordAuthenticationToken authenticationToken) {
        //仅在父类中验证用户的状态
    }

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String s, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
        try {
            UserDetails loadedUser = authenticationUser(usernamePasswordAuthenticationToken);
            if (loadedUser == null) {
                throw new InternalAuthenticationServiceException("");
            }
            return loadedUser;
        } catch (UsernameNotFoundException e) {
            throw e;
        } catch (InternalAuthenticationServiceException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new InternalAuthenticationServiceException(ex.getMessage(), ex);
        }
    }

    private UserDetails authenticationUser(UsernamePasswordAuthenticationToken authenticationToken) {
        if (authenticationToken.getPrincipal() == null) {
            throw new BadCredentialsException("username is blank");
        }
        String username = authenticationToken.getName();
        if (authenticationToken.getCredentials() == null) {
            throw new BadCredentialsException("Credentials is blank");
        }
        String credentials = authenticationToken.getCredentials().toString();
        AuthPrincipal authPrincipal = null;
        try {
            authPrincipal = JSON.parseObject(username, AuthPrincipal.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BadCredentialsException("username parseObject error");
        }
        if (authenticationToken.getDetails() instanceof Map) {
            Map detailsMap = (Map) authenticationToken.getDetails();
            authPrincipal.getPayload().putAll(detailsMap);
        }
        return authenticationHandler.authentication(authPrincipal, credentials);
    }
}
